package com.example.kafka.controller;

import com.example.kafka.common.Response;
import com.example.kafka.exception.SysException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/hello")
public class HelloController {

    @Resource(name = "fullMonitorWebClient")
    private WebClient client;

    @RequestMapping("/index")
    public String begin(){
        List<String> lists = new ArrayList<>();
        lists.add("948");
        post("/dbStandingBook/selectByIds",lists, Response.class);

        return "index";
    }

    /**
     * http post请求
     *
     * @param path      请求路径
     * @param request   请求body数据
     * @param resultClz 返回数据类型
     * @param <T>       请求body数据类型
     * @param <R>       返回数据类型
     * @return 不为<code>null<code/>
     */
    private <T, R> R post(String path, T request, Class<R> resultClz) {
        try {
            String body = new ObjectMapper().writeValueAsString(request);
            R result = client.post()
                    .uri(path)
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                    .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                    .body(BodyInserters.fromValue(body))
                    .retrieve()
                    .onStatus(HttpStatus::isError, this::onHttpError)
                    .bodyToMono(resultClz)
                    .retry(3)
                    .block();

            assert result != null;

            return result;
        } catch (Exception e) {
            if (!(e instanceof SysException)) {
                throw new SysException("an error occurred when run full-dose-monitor api", e);
            } else {
                throw (SysException) e;
            }
        }
    }

    private Mono<SysException> onHttpError(ClientResponse response) {
        return Mono.error(new SysException("an error occurred when run full-dose-monitor api, http status:{}", response.statusCode()));
    }
}
